package com.sca4cloud.sca.message.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

import com.alibaba.druid.util.StringUtils;
import com.sca4cloud.sca.common.security.service.ScaUser;
import com.sca4cloud.sca.common.security.util.SecurityUtils;
import com.sca4cloud.sca.message.constant.PublicConstant;

import lombok.extern.slf4j.Slf4j;

/**
 * Websocket 配置类
 *
 * @author shan.deng
 * @date 2020-07-15 16:06:44
 */
@Configuration
@EnableWebSocketMessageBroker
@Slf4j
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	private RestTemplate restTemplate = new RestTemplate();

	@Value("${security.oauth2.resource.token-info-uri}")
	private String auth_check_token_url;

	/**
	 * 注册STOMP协议的节点（endpoint）并映射指定的URL
	 * 
	 * @param registry
	 */
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/net").setAllowedOrigins("*").withSockJS();
	}

	/**
	 * 配置消息代理类
	 * 
	 * @param registry
	 */
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		// 广播式应配置一个消息结果消息代理
		registry.enableSimpleBroker("/net/result", "/result");
		registry.setUserDestinationPrefix("/net");
	}

	@Override
	public void configureClientInboundChannel(ChannelRegistration registration) {
		restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
			@Override
			// Ignore 400
			public void handleError(ClientHttpResponse response) throws IOException {
				if (response.getRawStatusCode() != 400) {
					super.handleError(response);
				}
			}
		});
		// 注册一个拦截器用来做权限校验
		registration.interceptors(new ChannelInterceptor() {
			@Override
			public Message<?> preSend(Message<?> message, MessageChannel channel) {
				StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
				// 判断是否首次连接
				if (StompCommand.CONNECT.equals(accessor.getCommand())) {
					ScaUser user = SecurityUtils.getUser();
					if (user != null) {
						accessor.setUser(new UserPrincipal(user.getUsername()));
						return message;
					}
//					CURRENT_USERNAME
					String username = accessor.getFirstNativeHeader("CURRENT_USERNAME");
					accessor.setUser(new UserPrincipal(username));
					return message;
					
//					String token = accessor.getFirstNativeHeader(HttpHeaders.AUTHORIZATION);
//					String tenantId = accessor.getFirstNativeHeader("TENANT-ID");
//					log.info("websocket token========{},tenantId={}", token, tenantId);
//					if (StringUtils.isEmpty(token)) {
//						return null;
//					}
//					if (!token.startsWith(PublicConstant.AUTH_PREFIX)) {
//						return null;
//					}
//					token = token.split(" ")[1];
//					HttpHeaders headers = new HttpHeaders();
//					headers.add("TENANT-ID", tenantId);
//					 Map<String, Object> requestBody = new HashMap<>();
//	                    HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(requestBody, headers);
//	                   
//					String url = auth_check_token_url + "?token=" + token;
//					Map<String, Object> map = restTemplate.postForObject(url, httpEntity, Map.class);
//					if (map != null && !map.containsKey("error")) {
//						if (map.get("user_name") != null) {
//							accessor.setUser(new UserPrincipal(map.get("user_name").toString()));
//							return message;
//						}
//					}
//					throw new RuntimeException("未授权");
				}
				return message;
			}
		});
	}
}
